package com.atguigu.gulimall.product;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * JSR303数据校验
 *  1：groups(分组校验)
 *
 *  (给校验注解，标注上groups，指定什么情况下才需要进行校验)
 *   groups里面的内容要以接口的形式显示出来
 *  自定义校验
 * 	 1：编写一个自定义的校验注解
 * 	 2：编写一个自定义的校验器
 * 	 3：关联自定义的校验器和自定义的校验注解
 *
 * 	2.整合redis
 * 	1).引入star-data-redis
 * 	2).简单配置redis的host信息
 * 	3).使用SprinBoot自动配置好的StringRedisTemplate来操作redis;
 * 	redis ->map  key -value
 * 	缓存的注解：CacheAutoConfiguration 会导入Redis CacheAutoConfiguration
 * 	@ cacheEvict:触发将数据从缓存中删除的操作
 *  @ cachePut:不影响方法执行更新缓存
 *  @ caching:组合以上多个操作
 *  @ cacheConfig:在类级别共享缓存的相同配置
 * 4.spring-cache的不足
 *   1).读模式 适合cache
 *    缓存穿透：查询一个null数据。解决：缓存空数据 spring.cache.redis.cache-null-values=true
 *    缓存击穿：大量并发进来的同时查询一个正好过期的数据：解决方案：加锁? 默认是无加锁的；@Cacheable里面属性 sync=true()查询加锁，本地锁进行
 *    缓存雪崩: 大量的key同时过期。解决:加随机时间，加上过期时间 spring.cache.redis.time-to-live=3600000
 *   2)写模式：(缓存与数据库一致)
 *      1).读写加锁
 *      2).引入Canal,感知到mysql的更新去更新缓存
 *      3).读多写多，直接去数据库查询进行
 *  总结：
 *      原理：CacheManager(RedisCacheManage)->Cache(RedisCache)->Cache负责缓存读写
 *      常规数据(读多写少，及时性，一致性要求不高的数据)=>完全可以使用sring-cache，写模式有过期
 *      时间将足够了。
 *      特殊数据:特殊设计
 *  @Validate
 */
@EnableRedisHttpSession
@EnableCaching
@MapperScan("com.atguigu.gulimall.product.dao")
@EnableFeignClients(basePackages = "com.atguigu.gulimall.product.feign")
@EnableDiscoveryClient
@SpringBootApplication
public class JiajialemallProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(JiajialemallProductApplication.class, args);
    }

}
